using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace CSharpClient
{
    class Program
    {
        // 回调委托定义
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void HttpCallback(string response, int errorCode);

        // DLL导入声明
        [DllImport("libCRequestLib.dylib", CallingConvention = CallingConvention.Cdecl)]
        private static extern void http_get_async(string url, HttpCallback callback);

        static async Task Main(string[] args)
        {
            Console.WriteLine("=== C语言HTTP请求库 C#客户端 ===");
            Console.WriteLine("运行环境: macOS");
            Console.WriteLine();

            while (true)
            {
                Console.WriteLine("请选择操作:");
                Console.WriteLine("1. 测试百度首页");
                Console.WriteLine("2. 测试自定义URL");
                Console.WriteLine("3. 批量测试");
                Console.WriteLine("4. 退出");
                Console.Write("请输入选择 (1-4): ");

                var choice = Console.ReadLine();
                
                switch (choice)
                {
                    case "1":
                        await TestBaidu();
                        break;
                    case "2":
                        await TestCustomUrl();
                        break;
                    case "3":
                        await BatchTest();
                        break;
                    case "4":
                        Console.WriteLine("感谢使用，再见！");
                        return;
                    default:
                        Console.WriteLine("无效选择，请重新输入。");
                        break;
                }
                
                Console.WriteLine();
            }
        }

        static async Task TestBaidu()
        {
            Console.WriteLine("正在请求百度首页...");
            await MakeRequest("http://www.baidu.com/");
        }

        static async Task TestCustomUrl()
        {
            Console.Write("请输入URL地址: ");
            var url = Console.ReadLine();
            
            if (string.IsNullOrWhiteSpace(url))
            {
                Console.WriteLine("URL不能为空！");
                return;
            }

            await MakeRequest(url);
        }

        static async Task BatchTest()
        {
            string[] testUrls = {
                "http://www.baidu.com/",
                "http://www.qq.com/",
                "http://www.sina.com.cn/",
                "http://www.sohu.com/"
            };

            Console.WriteLine($"开始批量测试 {testUrls.Length} 个网站...");
            
            for (int i = 0; i < testUrls.Length; i++)
            {
                Console.WriteLine($"\n[{i + 1}/{testUrls.Length}] 测试: {testUrls[i]}");
                await MakeRequest(testUrls[i]);
                
                // 稍微延迟一下，避免请求过快
                await Task.Delay(1000);
            }
            
            Console.WriteLine("\n批量测试完成！");
        }

        static async Task MakeRequest(string url)
        {
            try
            {
                var completionSource = new TaskCompletionSource<string>();
                var startTime = DateTime.Now;

                HttpCallback callback = (response, errorCode) =>
                {
                    var endTime = DateTime.Now;
                    var duration = (endTime - startTime).TotalMilliseconds;

                    if (errorCode == 0 && !string.IsNullOrEmpty(response))
                    {
                        Console.WriteLine($"✅ 请求成功！");
                        Console.WriteLine($"   响应时间: {duration:F2}ms");
                        Console.WriteLine($"   响应大小: {response.Length} 字节");
                        Console.WriteLine($"   前100字符: {response.Substring(0, Math.Min(100, response.Length))}...");
                        completionSource.SetResult(response);
                    }
                    else
                    {
                        Console.WriteLine($"❌ 请求失败！");
                        Console.WriteLine($"   错误码: {errorCode}");
                        Console.WriteLine($"   错误信息: {GetErrorMessage(errorCode)}");
                        completionSource.SetException(new Exception($"HTTP请求失败，错误码: {errorCode}"));
                    }
                };

                http_get_async(url, callback);
                await completionSource.Task;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"💥 发生异常: {ex.Message}");
            }
        }

        static string GetErrorMessage(int errorCode)
        {
            return errorCode switch
            {
                0 => "成功",
                1 => "网络错误",
                2 => "无效URL",
                3 => "请求失败", 
                4 => "内存错误",
                _ => "未知错误"
            };
        }
    }
}
